//
//  XXNavigationController.swift
//  APP
//
//  Created by Rdxer on 2017/12/9.
//  Copyright © 2017年 Rdxer. All rights reserved.
//

import UIKit
import FastComponent

 
public enum XXAppNvcResult {
    case successful(Para)
    case failure(Para)
    case cancel(Para)
    case none
    
    public enum Para {
        case code(Int)
        case object(AnyObject)
        case empty
        case Option_1
        case Option_2
        case Option_3
    }
    
    public struct Source {
        // TODO: 测试
        //        weak var vc:UIViewController?
        var vc:UIViewController?
        init(vc:UIViewController?) {
            self.vc = vc
        }
    }
}

/// 跳转控制
public protocol XXAppNavigationControllerJumpDelegate {
    var appNvcResult:XXAppNvcResult{get}
    var appNvcSource:XXAppNvcResult.Source{get}
}

/// UIViewController
public extension XXAppNavigationControllerJumpDelegate  where Self: UIViewController {
    var appNvcSource: XXAppNvcResult.Source{
        return XXAppNvcResult.Source.init(vc: self)
    }
}

/// 基础代理
public protocol XXAppNavigationControllerDelegate {
    /// 是否允许侧滑返回  默认 true
    var allowSideslip:Bool{get}
    
    var xx_hidesBottomBarWhenPushed:Bool{get}
    
    var navigationBarHidden:Bool?{get}
    
    /// 点击 返回 摁钮之后 拦截点击事件
    /// 如需 继续 事件 调用 completeHandle
    /// 否则 则 丢弃 此点击事件
    /// 默认 自动调用 completeHandle
    func backButtonClick(_ nav:XXAppNavigationController, completeHandle:@escaping (_ nav:XXAppNavigationController)->())
    
    /// 返回到 此界面
    /// 默认 不做任何事情
    func navDidPopTo(_ nav:XXAppNavigationController, viewControllers:[UIViewController]?,source:XXAppNvcResult.Source?,appNvcResult:XXAppNvcResult)
}
extension XXAppNavigationControllerDelegate{
    /// 是否允许侧滑返回  默认 true
    public var allowSideslip:Bool{
        return true
    }
    
    public var xx_hidesBottomBarWhenPushed:Bool{
        return true
    }
    
    
    public var navigationBarHidden:Bool?{
        return nil
    }
    
    
    public func backButtonClick(_ nav:XXAppNavigationController, completeHandle:@escaping (_ nav:XXAppNavigationController)->()){
        completeHandle(nav)
    }
    
    public func navDidPopTo(_ nav: XXAppNavigationController, viewControllers: [UIViewController]?, source: XXAppNvcResult.Source?, appNvcResult: XXAppNvcResult) {
        
    }
}



/// 自定义 左侧返回图标之后仍然能侧滑的 NVC
open class XXAppNavigationController: XXBaseNavigationController,UIGestureRecognizerDelegate,UINavigationControllerDelegate {
    
    
    
    open  override var supportedInterfaceOrientations: UIInterfaceOrientationMask{
        return (topViewController?.supportedInterfaceOrientations) ?? .all
    }
    
    open  override var shouldAutorotate: Bool{
        return (topViewController?.shouldAutorotate) ?? true
    }
    
    open  override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{
        return (topViewController?.preferredInterfaceOrientationForPresentation) ?? .portrait
    }
    
    open  override var preferredStatusBarStyle: UIStatusBarStyle {
        guard let topViewController = topViewController else {
            return .default
        }
        return topViewController.preferredStatusBarStyle
    }
    
    open override  func viewDidLoad() {
        super.viewDidLoad()
        prepareGestureRecognizerDelegate()
        
        self.delegate = self
        
        initAppearance()
        
    }
    
    open func initAppearance(){
        self.view.backgroundColor = FastComponentStyle.style.backgroundColor
        navigationBar.titleTextAttributes = [
            NSAttributedString.Key.foregroundColor:FastComponentStyle.style.textColor
        ]
    }
    
    open override func pushViewController(_ viewController: UIViewController, animated: Bool) {
        
        if self.viewControllers.count > 0 {
            
            var image =  FastComponentBundle.imageWithSelf(name: "nav_bar_back_icon")?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
            
            if #available(iOS 13.0, *) {
                image = image?.withTintColor(UIColor.gray)
            } else {
                // Fallback on earlier versions
            }
            
            let barButton = UIBarButtonItem.init(image: image, style: .done, target: self, action: #selector(backButtonClick))
            
            viewController.navigationItem.leftBarButtonItem = barButton
            
            if let _d = viewController as? XXAppNavigationControllerDelegate{
                viewController.hidesBottomBarWhenPushed = _d.xx_hidesBottomBarWhenPushed
            }else{
                viewController.hidesBottomBarWhenPushed = true
            }
        }
        
        super.pushViewController(viewController, animated: animated)
    }
    
    @objc func backButtonClick(){
        
        if let _d = self.topViewController as? XXAppNavigationControllerDelegate{
            _d.backButtonClick(self) {nvc in
                nvc.popViewController(animated: true)
            }
            return
        }
        
        self.popViewController(animated: true)
    }
    
    @discardableResult
    open  override func popViewController(animated: Bool) -> UIViewController? {
        
        let vcByPop = super.popViewController(animated: animated)
        /// 已经 pop 完成
        
        if let _vcByCurrenty = self.topViewController as? XXAppNavigationControllerDelegate{
            var array:[UIViewController] = []
            
            if let vt = vcByPop{
                array.append(vt)
            }
            
            var res = XXAppNvcResult.none
            var source:XXAppNvcResult.Source?
            
            if let _dd = vcByPop as? XXAppNavigationControllerJumpDelegate{
                res = _dd.appNvcResult
                source = _dd.appNvcSource
            }
            
            _vcByCurrenty.navDidPopTo(self, viewControllers: array, source: source, appNvcResult: res)
        }
        return vcByPop
    }
    
    @discardableResult
    open  override func popToRootViewController(animated: Bool) -> [UIViewController]? {
        
        let vs = super.popToRootViewController(animated: animated)
        
        if let _d = self.topViewController as? XXAppNavigationControllerDelegate{
            
            var res = XXAppNvcResult.none
            var source:XXAppNvcResult.Source?
            
            if let _dd = vs?.last as? XXAppNavigationControllerJumpDelegate{
                res = _dd.appNvcResult
                source = _dd.appNvcSource
            }
            
            _d.navDidPopTo(self, viewControllers: vs, source: source, appNvcResult: res)
        }
        
        return vs
    }
    
    open func prepareGestureRecognizerDelegate(){
        self.interactivePopGestureRecognizer?.delegate = self
    }
    
    open func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        if self.viewControllers.count > 1 {
            
            if let _d = self.topViewController as? XXAppNavigationControllerDelegate{
                return _d.allowSideslip
            }
            
            return true
        }
        return false
    }
    open func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
    open func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return gestureRecognizer.isKind(of: UIScreenEdgePanGestureRecognizer.self)
    }
    
    // MARK: -
    // MARK: - 控制 navigationBarHidden 显示隐藏
    private var navigationBarHiddenByViewControllerClass:[AnyClass] = []
    open func registerNavigationBarHiddenByViewControllerClass(vcClass:AnyClass){
        navigationBarHiddenByViewControllerClass.append(vcClass)
    }
    
    open func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        
        if let delegate = viewController as? XXAppNavigationControllerDelegate, let hide = delegate.navigationBarHidden{
            setNavigationBarHidden(hide, animated: true)
        }else{
            setNavigationBarHidden(viewController.isKind(classList: navigationBarHiddenByViewControllerClass), animated: true)
        }
    }
}


//public extension XXExtension where Base:UIViewController {
public extension UIViewController {
    func xx_wrapNavigation(modalPresentationStyle:UIModalPresentationStyle  = .fullScreen)->XXAppNavigationController{
        
        let nav = XXAppNavigationController.init(rootViewController: self)

        let button = UIButton.init(type: .custom)
        
        button.image = FastComponentBundle.imageWithSelf(name: "close")
        
        let ba = self
        
        button.rx.tap.subscribeOnNext { [weak ba](_) in
            ba?.dismiss(animated: true, completion: nil)
        }.disposed(by: button)

        let closeBarButton = UIBarButtonItem.init(customView: button)

        navigationItem.leftBarButtonItem = closeBarButton

        nav.modalPresentationStyle = modalPresentationStyle
        
        return nav
    }
}
